home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 November: Tool Chest / Dev.CD Nov 98 TC.toast / Sample Code / Networking / OTLLCTest / NegotiateRawModeSample.c next >
Encoding:
C/C++ Source or Header  |  1998-09-13  |  6.5 KB  |  197 lines  |  [TEXT/MMCC]

  1. /*
  2.     File NegotiateRawModeSample.c
  3.     
  4.     By: Rich Kubota
  5.     Developer Technical Support
  6.     updated September 12, 1998
  7.     
  8.     
  9.     This sample demonstrates the use of Option Management to place an Ethernet
  10.     endpoint into raw mode.  In addition, the sample distinguishes whether the
  11.     ethernet driver is based on the original Ethernet template that was used on
  12.     the Power Mac 72/73/75/76/85/86/95/9600 systems. Under SSW 8.5, the ethernet
  13.     driver will be based on the Apple Ethernet template which is a modification 
  14.     of the Mentat template customized to the Mac OS. For the purposes of
  15.     enabling and using raw mode, the Apple Ethernet template can be considered
  16.     the same as the mentat template.
  17.     
  18.     BACKGROUND
  19.     As of the release of OpenTransport 1.1.1, a new driver template, provided
  20.     by Mentat, was released.  This new driver template is simpler to use and
  21.     provides a standard mechanism for handling promiscuous mode.
  22.     
  23.     There are 2 important differences between these two templates.  The mechanism
  24.     by which an Ethernet endpoint is placed into raw mode is different.  In addition,
  25.     the raw mode packet that the mentat based driver passes, must be handled
  26.     differently from packets passed up by the original ethernet drivers.
  27.     
  28.     OBJECTIVE:
  29.     This code snippet has been modified to do 2 things
  30.     1. demonstrate a method for placing an ethernet endpoint into raw mode regardless
  31.     of the template type that the underlying driver is based on, and,
  32.     2. to return the template type so that the caller will know how to correctly
  33.     handle the raw mode packets.
  34.     
  35.     FOR USERS OF PREVIOUS VERSIONS OF THIS CODE
  36.     
  37.     IMPORTANT Note: This sample does not support asynchronous endpoints. The technique
  38.     of checking whether the endpoint is async on entry to this function and changing
  39.     it to sync, can work under some cases, however, this is not always true.
  40.     If an async endpoint must be used, then modify the following code as appropriate
  41.     to work with a handler routine that handles the T_OPTMGMTCOMPLETE event.  The cookie
  42.     will be a pointer to the returned TOptMgmt structure so that you can check the 
  43.     negotiation result.
  44.     
  45.     Input parameters:
  46.     EndpointRef - ethernet endpoint that you want to place into raw mode.
  47.     rawModeOption - one of the following values
  48.                     kOTRawRcvOn    - enable raw mode
  49.                     kOTRawRcvOff - disable raw mode
  50.                     
  51.                         // where the mentat template is present
  52.                     kOTRawRcvOnWithTimeStamp - enable raw mode and return timestamp
  53.     
  54.     return paramters:
  55.     result - kOTNoError if the raw mode option was successfully negotiated
  56.              < 0 OptionManagement call failed with the returned error
  57.              > 0 OptionManagement call completed with no error, but the negotiation
  58.                      returned a result other than T_SUCCESS
  59.     templateType - type of ethernet template that was detected.
  60.                     kUnknownTemplate
  61.                     kOrigTemplate,
  62.                     kMentatTemplate
  63.  
  64.     raw mode data -
  65.     An ethernet driver based on the original template will return the ethernet packet
  66.     in the OTRcvUData buffer such that the destination address begins at offset 0 in
  67.     the buffer.  A Mentat based driver will prepend the ethernet packet with the 
  68.     following structure so that the destination packet begins at offset 0x18.
  69.     
  70.     struct dl_recv_status_t {
  71.     unsigned long    dl_overall_length;
  72.     unsigned long    dl_flags;
  73.     unsigned long    dl_packet_length_before_truncation;
  74.     unsigned long    dl_pad;
  75.     OTTimeStamp        dl_timestamp;
  76.     };
  77.     
  78.     This structure is defined in the file dlpiuser.h.  This header is found in the 
  79.     OT Modules Development samples folder of the OT SDK.
  80.  
  81.  
  82. */
  83. #include <Gestalt.h>
  84. #include "NegotiateRawModeSample.h"
  85. #include "OpenTptLinks.h"
  86.  
  87. static Boolean    IsDesiredOTVersionPresent(UInt32 desVers);
  88.  
  89. // important note - use the options as defined in the OpenTptLinks.h header
  90. // when setting the rawModeOption parameter.
  91. pascal OSStatus DoNegotiateRawModeOption(EndpointRef ep, 
  92.                                         UInt32 rawModeOption, 
  93.                                         UInt32 *templateType)
  94.  
  95. {
  96.     UInt8        twelveByteOptionBuf[kOTOptionHeaderSize+12];
  97.     dl_recv_control_t *rawModePtr;
  98.     UInt8        buf[kOTFourByteOptionSize];    // define buffer for fourByte Option size
  99.     TOption*    opt;                        // option ptr to make items easier to access
  100.     TOptMgmt    req;
  101.     TOptMgmt    ret;
  102.     OSStatus    err;
  103.     
  104.     
  105.     *templateType = kUnknownTemplate;        // intialize the template type return value
  106.     
  107.     opt = (TOption*)buf;                    // set option ptr to buffer
  108.     req.opt.buf    = buf;
  109.     req.opt.len    = sizeof(buf);
  110.     req.flags    = T_NEGOTIATE;                // negotiate for rawmode option
  111.  
  112.     ret.opt.buf = buf;
  113.     ret.opt.maxlen = kOTFourByteOptionSize;    // first try the four-byte option request
  114.     
  115.  
  116.     opt->level    = LNK_TPI;                    // dealing with tpi
  117.     opt->name    = OPT_SETRAWMODE;
  118.     opt->len    = kOTFourByteOptionSize;
  119.     opt->status = 0;
  120.     *(UInt32*)opt->value = rawModeOption;        // set the desired option level, true or false
  121.  
  122.     if (OTIsSynchronous(ep) == false)            // check whether ep sync or not
  123.     {
  124.         DebugStr("\p DoNegotiateRawModeOption does not support async endpoints");
  125.         return (-1);
  126.     }
  127.                 
  128.     err = OTOptionManagement(ep, &req, &ret);
  129.         
  130.         // if no error then return the option status value
  131.     if (err == kOTNoError)
  132.     {
  133.         if (opt->status != T_SUCCESS)
  134.             err = opt->status;
  135.         else
  136.             *templateType = kOrigTemplate;    // the negotiation succeeded so we are dealing
  137.                                             // with a driver based on orig template
  138.     }
  139.     
  140.     if (err != kOTNoError)
  141.     {
  142.             // check if OT 1.2 or greater is present
  143.             // there is a bug in the tpi8022 module in OT <= v1.1.x, such that 12 byte raw modes
  144.             // options are not passed to the dlpi module and an IONACK result is returned.
  145.         if (IsDesiredOTVersionPresent(kOTVers12))
  146.         {
  147.                 // let's try the 12 byte option
  148.             opt = (TOption*)twelveByteOptionBuf;    // set option ptr to buffer
  149.             req.opt.buf    = twelveByteOptionBuf;
  150.             req.opt.len    = sizeof(twelveByteOptionBuf);
  151.             req.flags    = T_NEGOTIATE;                // negotiate for rawmode option
  152.  
  153.             ret.opt.buf = twelveByteOptionBuf;
  154.             ret.opt.maxlen = sizeof(twelveByteOptionBuf);
  155.  
  156.             opt->level    = LNK_TPI;                    // dealing with tpi
  157.             opt->name    = OPT_SETRAWMODE;
  158.             opt->len    = sizeof(twelveByteOptionBuf);
  159.             opt->status = 0;
  160.             
  161.             rawModePtr = (dl_recv_control_t*)&opt->value;
  162.             rawModePtr->dl_primitive = kOTSetRecvMode;
  163.             rawModePtr->dl_flags = DL_NORMAL_STATUS;
  164.             rawModePtr->dl_truncation_length = 0;
  165.             
  166.             err = OTOptionManagement(ep, &req, &ret);
  167.  
  168.                 // if no error then return the option status value
  169.             if (err == kOTNoError)
  170.             {
  171.                 if (opt->status != T_SUCCESS)
  172.                     err = opt->status;
  173.                 else
  174.                     *templateType = kMentatTemplate;
  175.             }
  176.             
  177.         }
  178.         
  179.     }
  180.  
  181.     return err;
  182. }
  183.  
  184. /*
  185. */
  186.  
  187. Boolean    IsDesiredOTVersionPresent(UInt32 desVers)
  188. {
  189.     OSErr    err;
  190.     UInt32    otVersion;
  191.     
  192.     err = Gestalt(gestaltOpenTptVersions, (long*) &otVersion);
  193.     if (err)
  194.         return false;
  195.     else
  196.         return (otVersion >= desVers);
  197. }